home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Graphics⁄Sound / Star Stuff / star.c next >
Encoding:
C/C++ Source or Header  |  1986-03-20  |  7.7 KB  |  343 lines  |  [TEXT/????]

  1. /*
  2.     Star Chart
  3.         Originally written in DeSmet C for the Macintosh by
  4.             David Palmer
  5.             Mail Code 220-47
  6.             California Institute Of Technology
  7.             Pasadena CA, 91125
  8.  
  9.     The Data File is in the public domain
  10.     This Program is copyright 1986 By David Palmer,
  11.     It may be copied, modified, or given away, but not sold.
  12.     Anybody making substantial improvements must distribute the improved version
  13.     under the same conditions, and send me a copy of the improved program.
  14. */
  15.  
  16. #include <quickdraw.h>  
  17. #include <window.h>
  18. #include <menu.h>
  19. #include <event.h>
  20. #include <textedit.h>
  21. #include <dialog.h>
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include "star.h"
  25.  
  26. int nstars = 0;
  27.  
  28. star *cat;
  29. double atof();
  30.  
  31. #define Bool10(f) (f ? 1 : 0)
  32.  
  33. /* DeSmet C bug: DeSmet C, when casting floats into integers, rounds instead */
  34. /* of truncating, a flagrant violation of the standard, for which the author */
  35. /* should be forced to use BASIC */
  36. int makeint(i)
  37. double i;
  38. {
  39.     if ((i > 0 && i > (int) i) || (i < 0 && i < (int) i))
  40.         return (int) i;
  41.     else if (i > 0)
  42.         return (int)i - 1;
  43.     else if (i < 0)
  44.         return (int)i + 1;
  45. }
  46.     
  47. InitAll()
  48. {
  49.     InitGraf(&thePort);
  50.     InitFonts();
  51.     InitWindows();
  52.     InitMenus();
  53.     TEInit();
  54.     InitDialogs(0L);
  55.     InitCursor();
  56.     if (-1 == OpenResFile(RESFILE)) {
  57.         printf("Cannot open resource file\n");
  58.         sysbeep(20);
  59.         exit();
  60.     }
  61.     GetCat(STARFILE);
  62. }
  63.  
  64. GetCat(fName)
  65. char *fName;
  66. {
  67.     FILE *fcat, *fopen();
  68.  
  69.     nstars = NSTARS;
  70.     cat = lmalloc((long)NSTARS * (long)sizeof(star));
  71.     if (cat == NULL) {
  72.         printf("Not enough memory to run stars\n");
  73.         sysbeep(20);
  74.         exit();
  75.     }
  76.  
  77.     fcat = fopen(fName, "r");
  78.     if (fcat == NULL) {
  79.         printf("File not openable\n");
  80.         exit();
  81.     }
  82.     setbinary(*fcat);                    /* Do not map CR=>CRLF or vice-versa    */
  83.     fread(cat, nstars, sizeof(star), fcat);
  84.     fclose(fcat);
  85. }
  86.  
  87. DrawMap(pg, philook, thetalook, size, maglabel, fblack, fcross, flabel)
  88. GrafPort *pg;
  89. double philook, thetalook, size;    /* All in radians */
  90. int fblack, fcross;
  91. int maglabel, flabel;
  92. {
  93.     float scale;
  94.     long u, v, w;    /* coordinates in right, up, forward directions */ 
  95.     long forward[3], right[3], up[3];
  96.     int xmax, ymax, xcenter, ycenter;
  97.     int i;
  98.     Rect rc;
  99.  
  100.     TextFont(1);
  101.     TextSize(9);
  102.     TextMode(srcXor);
  103.     forward[X] = DIST * sin(thetalook) * cos(philook);
  104.     forward[Y] = DIST * sin(thetalook) * sin(philook);
  105.     forward[Z] = DIST * cos(thetalook);
  106.     up[X] = DIST * sin(thetalook - (PI/2)) * cos(philook);
  107.     up[Y] = DIST * sin(thetalook - (PI/2)) * sin(philook);
  108.     up[Z] = DIST * cos(thetalook - (PI/2));
  109.     right[X] = (forward[Y] * up[Z] - forward[Z] * up[Y])/DIST;
  110.     right[Y] = (forward[Z] * up[X] - forward[X] * up[Z])/DIST;
  111.     right[Z] = (forward[X] * up[Y] - forward[Y] * up[X])/DIST;
  112.  
  113.     PenNormal();
  114.     PaintRect(pg->portRect);
  115.     if (!fblack)
  116.         InvertRect(pg->portRect);
  117.     xmax = pg->portRect.right;
  118.     ymax = pg->portRect.bottom;
  119.     scale = ((float)xmax)/(3.2e4 * 2 * sin(size/2));
  120.     xcenter = xmax/2;
  121.     ycenter = ymax/2;
  122.     for (i = 0 ; i < nstars ; i++) {
  123.         w = ((long)cat[i].x * forward[X] + (long)cat[i].y * forward[Y] +
  124.                         (long)cat[i].z * forward[Z])/DIST;
  125.         if (0. < (float)w) {
  126. /* DeSmet C bug: If the "+-" in the next line is changed to a "-", strange things */
  127. /* happen, due to a DeSmet compiler bug (at least in version 1.01) */
  128.             v = ycenter +- (scale * ((long)cat[i].x * up[X] + 
  129.                     (long)cat[i].y * up[Y] +(long)cat[i].z * up[Z]))/w;
  130.             if (0 < v  && v < ymax) {
  131.                 u = xcenter + (scale * ((long)cat[i].x * right[X] +
  132.                         (long)cat[i].y * right[Y] + (long)cat[i].z * right[Z]))/w;
  133.                 if (0 < u && u < xmax) {
  134.                     rc.left = u - (700 - cat[i].mag)/200;
  135.                     rc.right = rc.left + (700 - cat[i].mag)/100;
  136.                     rc.top = v - (700 - cat[i].mag)/200;
  137.                     rc.bottom = rc.top + (700 - cat[i].mag)/100;
  138.                     invertoval(rc);
  139.                     if (flabel && cat[i].mag < maglabel) {
  140.                         MoveTo(rc.right+2, rc.bottom);
  141.                         DrawText(&cat[i].name , 0, 6);
  142.                     }
  143.                 }
  144.             }
  145.         }
  146.     }
  147.     penmode(patXor);
  148.     if (fcross) {
  149.         moveto(xcenter - 5, ycenter); lineto(xcenter + 5, ycenter);
  150.         moveto(xcenter, ycenter - 5); lineto(xcenter, ycenter + 5);
  151.     }
  152. }
  153.  
  154. GetNText(pdi, itemno, pch)
  155. DialogPtr pdi;
  156. int itemno;
  157. char *pch;
  158. {
  159.     long type;
  160.     Handle item;
  161.     Rect box;
  162.  
  163.     GetDItem(pdi, itemno, &type, &item, &box);
  164.     GetIText(item, pch);
  165. }
  166.  
  167. SetNText(pdi, itemno, pch)
  168. DialogPtr pdi;
  169. int itemno;
  170. char *pch;
  171. {
  172.     long type;
  173.     Handle item;
  174.     Rect box;
  175.  
  176.     GetDItem(pdi, itemno, &type, &item, &box);
  177.     SetIText(item, pch);
  178. }
  179.  
  180. SetNValue(pdi, itemno, value)
  181. DialogPtr pdi;
  182. int itemno;
  183. int value;
  184. {
  185.     long type;
  186.     Handle item;
  187.     Rect box;
  188.  
  189.     GetDItem(pdi, itemno, &type, &item, &box);
  190.     SetCtlValue(item, value);
  191. }
  192.  
  193. int GetNValue(pdi, itemno)
  194. DialogPtr pdi;
  195. int itemno;
  196. {
  197.     long type;
  198.     Handle item;
  199.     Rect box;
  200.  
  201.     GetDItem(pdi, itemno, &type, &item, &box);
  202.     return GetCtlValue(item);
  203. }
  204.  
  205. SetNhms(pdi, ci, itemno, angle)    /* ci is number of items, angle is decimal hours */
  206. DialogPtr pdi;
  207. int ci, itemno;
  208. double angle;
  209. {
  210.     int unit;
  211.     char rgch[10];
  212.     int i, sig = 1;
  213.     double twiddle = 0.5;
  214.  
  215.     if (angle < 0) {
  216.         sig = -1;
  217.         angle = -angle;
  218.     }
  219.  
  220.     for (i = 1 ; i < ci ; i++)
  221.         twiddle /= 60.;
  222.     angle += twiddle;
  223.     for (i = 0 ; i < ci ; i++) {
  224.         unit = makeint(angle);
  225.         sprintf(rgch, "%d", unit);
  226.         SetNText(pdi, itemno + i, rgch);
  227.         angle = 60 * (angle - unit);
  228.     }
  229. }
  230.  
  231. double GetNhms(pdi, ci, itemno)
  232. DialogPtr pdi;
  233. int ci, itemno;
  234. {
  235.     char rgch[257];
  236.     double angle = 0;
  237.     int i;
  238.     int sig = 1;
  239.     double fraction = 1;
  240.  
  241.     for (i = 0 ; i < ci ; i++) {
  242.         GetNText(pdi, itemno+i, rgch);
  243.         angle += atof(rgch)*fraction;
  244.         if (angle < 0 || (i == 0 && rgch[0] == '-')) {
  245.             sig = -1;
  246.             angle = fabs(angle);
  247.         }
  248.         fraction /= 60;
  249.     }
  250.     return sig*angle;
  251. }
  252.  
  253. int DoDialog(pphi, ptheta, pwidth, pmaglabel, pfblack, pfcross, pflabel)
  254. double *pphi, *ptheta, *pwidth;
  255. int *pmaglabel, *pflabel;
  256. int *pfblack, *pfcross;
  257. {
  258.     DialogPtr pdi, pdi2;
  259.     double phi, theta;
  260.     int itemhit, item2;
  261.     char rgch[257];
  262.     int sig = 1;
  263.  
  264.     pdi = GetNewDialog(DIDget, 0l, -1l);
  265.  
  266.     SetNhms(pdi, 3, TErah, RtoH * *pphi);
  267.     theta = PIo2 + 1.e-7 - *ptheta;
  268.     SetNValue(pdi, RBn, Bool10(theta > 0));
  269.     SetNValue(pdi, RBs, Bool10(theta <= 0));
  270.     SetNhms(pdi, 3, TEdecd, RtoD * fabs(theta));
  271.     SetNhms(pdi, 1, TEwid, RtoD * *pwidth);
  272.     sprintf(rgch, "%0.2f", (double)*pmaglabel /100.);
  273.     SetNText(pdi, 16, rgch);
  274.     SetNValue(pdi, CBblack, Bool10(*pfblack));
  275.     SetNValue(pdi, CBcross, Bool10(*pfcross));
  276.     SetNValue(pdi, CBlabel, Bool10(*pflabel));
  277.  
  278.     do {
  279.         ModalDialog(0l, &itemhit);
  280.         switch (itemhit) {
  281.             case BUTok:
  282.             case BUTcan:
  283.                 break;
  284.             case BUTblame:
  285.                 pdi2 = GetNewDialog(DIDblame, 0l, -1l);
  286.                 do {
  287.                     ModalDialog(0l, &item2);
  288.                 } while (item2 != BUTok);
  289.                 CloseDialog(pdi2);
  290.                 break;
  291.             case CBlabel:
  292.             case CBcross:
  293.             case CBblack:
  294.                 SetNValue(pdi, itemhit, (GetNValue(pdi, itemhit) ? 0 : 1));
  295.                 break;
  296.             case RBn:
  297.             case RBs:
  298.                 SetNValue(pdi, RBn, Bool10(!(itemhit & 1)));
  299.                 SetNValue(pdi, RBs, Bool10(itemhit & 1));
  300.             case TEmaglabel:
  301.             default:
  302.                 break;
  303.         }
  304.     } while (itemhit != BUTok && itemhit != BUTcan);
  305.     if (itemhit == BUTcan) return 0;
  306.     *pfcross = GetNValue(pdi, CBcross);
  307.     *pfblack = GetNValue(pdi, CBblack);
  308.     *pflabel = GetNValue(pdi, CBlabel);
  309.     *pphi = GetNhms(pdi, 3, TErah) * HtoR;
  310.     *pwidth = DtoR * GetNhms(pdi, 1, TEwid);
  311.     *pmaglabel = 100 * GetNhms(pdi, 1, TEmaglabel);
  312.     theta = GetNhms(pdi, 3, TEdecd) * DtoR;
  313.     if (GetNValue(pdi, RBn))
  314.         *ptheta = PIo2 - theta;
  315.     else
  316.         *ptheta = PIo2 + theta;
  317.     CloseDialog(pdi);
  318.     return -1;
  319. }
  320.  
  321. main()
  322. {
  323.     EventRecord theEvent;
  324.     double phi = 1.43990,
  325.         theta = 1.570796,
  326.         width = 1.047;
  327.     int fblack = 1,
  328.         fcross = 1;
  329.     int maglabel = 200,
  330.         flabel = 0;
  331.  
  332.     InitAll();
  333.     FlushEvents(0xffff, 0);
  334.     while (DoDialog(&phi, &theta, &width, &maglabel, &fblack, &fcross, &flabel)) {
  335.         HideCursor();
  336.         DrawMap(thePort, phi, theta, width, maglabel, fblack, fcross, flabel);
  337.         ShowCursor();
  338.         ObscureCursor();            /* Keep the cursor out of sight */
  339.         while (!Button()) GetNextEvent(0xffff, &theEvent);
  340.         while (Button())    ;
  341.         FlushEvents(0xffff, 0);
  342.     }
  343. }